<script setup lang="ts">
import { getArticleDetailAPI, pubArticleAPI, updateArticleAPI, uploadImageAPI } from '@/apis/user'
import ChannelSelect from '@/components/ChannelSelect.vue'
import type { PublishArticleParams } from '@/types/index'
import {
  ElMessage,
  type ElUpload,
  type FormInstance,
  type FormRules,
  type UploadRequestOptions,
  type UploadUserFile,
} from 'element-plus'
import { defineComponent, ref } from 'vue'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router'
defineComponent({
  name: 'ArticlePub',
})
// 发布文章数据
const pubData = ref<PublishArticleParams>({
  title: '',
  content: '',
  cover: { type: 1, images: [] },
  channel_id: null,
})
const formRef = ref<FormInstance>()
const formRules = ref<FormRules<PublishArticleParams>>({
  title: [
    { required: true, message: '请输入文章标题', trigger: 'blur' },
    { min: 3, max: 30, message: '长度在 3 到 30 个字符', trigger: 'blur' },
  ],
  content: [{ required: true, message: '请输入文章内容', trigger: 'blur' }],
  channel_id: [{ required: true, message: '请选择文章频道', trigger: 'change' }],
  cover: [
    {
      validator: (rule, value, callback) => {
        // console.log('value',value)
        if (value.type === 1 && value.images.length < 1) {
          return callback(new Error('请上传封面图'))
        } else if (value.type === 3 && value.images.length < 3) {
          return callback(new Error('请上传三张图片'))
        }
        callback()
      },
      trigger: 'change',
    },
  ],
})

// 图片上传
const uploadRef = ref<InstanceType<typeof ElUpload>>()
// 上传的图片预览
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const fileList = ref<UploadUserFile[]>([])

// 上传图片
const uploadFile = async (options: UploadRequestOptions) => {
  // console.log('uploadFile',options)
  const fd = new FormData()
  fd.append('image', options.file)
  const res = await uploadImageAPI(fd)
  // console.log('images',res)
  pubData.value.cover.images.push(res.data.url)
  formRef.value?.validateField('cover')
  return res.data.url
}
// 删除图片
const onRemove = (file: UploadUserFile) => {
  // console.log('onRemove',file)
  const index = pubData.value.cover.images.findIndex(
    (item: string | undefined) => item === file.url,
  )
  pubData.value.cover.images.splice(index, 1)
  formRef.value?.validateField('cover')
}

// 切换封面类型
const changeCoverType = () => {
  // console.log('changeCoverType', pubData.value.cover.type)
  uploadRef.value?.clearFiles()
  pubData.value.cover.images = []
  // 调用自定义校验
  formRef.value?.validateField('cover')
}
// 富文本配置
const editorOptions = {
  modules: {
    toolbar: [
      [{ header: [1, 2, 3, 4, 5, 6, false] }],
      ['bold', 'italic', 'underline', 'strike'],
      [{ list: 'ordered' }, { list: 'bullet' }],
      ['link', 'image', 'video'],
      ['clean'],
    ],
  },
  placeholder: 'Compose an epic...',
  theme: 'snow',
}
const cotentRef = ref<typeof QuillEditor>()
const onCheckContent = () => {
  // console.log('onCheckContent',pubData.value.content)
  // if (pubData.value.content === '<p><br></p>' || pubData.value.content === '') {
  //   cotentRef.value?.setHTML('')
  //   formRef.value?.validateField('content')
  // }
  formRef.value?.validateField('content')
}

const router = useRouter()
// 发布文章校验
const onSubmit = async (draft: boolean) => {
  try {
    await formRef.value?.validate()
    // 发布文章
    await pubArticleAPI(draft, pubData.value)
    // console.log('res',res)
    ElMessage.success(draft ? '已保存草稿' : '发布成功')
    router.push('/article')
  } catch {}
}
// 编辑文章
const onEdit = async (draft: boolean) => {
  // 修改文章
  try {
    await formRef.value?.validate()
    await updateArticleAPI(route.params.id as string, draft, pubData.value)
    ElMessage.success(draft ? '已保存草稿' : '修改成功')
    router.push('/article')
  } catch {}
}

const route = useRoute()
// 获取文章详情
const getArticleDetail = async () => {
  const res = await getArticleDetailAPI(route.params.id as string)
  // console.log('detail',res)
  // 回显数据
  const { title, content, channel_id, cover } = res.data
  pubData.value = { title, content, channel_id, cover }
  // console.log('cover',cover)
  // 回显图片
  if (cover.images.length > 0) {
    cover.images.forEach((item: string) => {
      fileList.value.push({
        name: item,
        url: item,
      })
    })
  }
}

if (route.params.id) {
  // 获取文章详情
  getArticleDetail()
}

// 组件内路由守卫
// 在当前路由改变，但是该组件被复用时调用
// 举例来说，对于一个带有动态参数的路径 `/users/:id`，在 `/users/1` 和 `/users/2` 之间跳转的时候，
// 由于会渲染同样的 `UserDetails` 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
onBeforeRouteUpdate((to) => {
  // 当路由变化时，如果路由有id，则获取文章详情
  if (to.params.id) {
    getArticleDetail()
  } else {
    // 重置表单和图片
    formRef.value?.resetFields()
    // 清空图片列表和富文本内容
    fileList.value = []
    cotentRef.value?.setHTML('')
  }
})
</script>

<template>
  <el-card>
    <!-- {{ fileList }} -->
    <template #header>
      <!-- 面包屑导航 -->
      <el-breadcrumb separator=">">
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>{{ $route.params.id ? '编辑文章' : '发布文章' }}</el-breadcrumb-item>
      </el-breadcrumb>
    </template>
    <!-- 主体：表单 -->
    <el-form ref="formRef" label-width="120px" :model="pubData" :rules="formRules">
      <el-form-item label="标题：" prop="title">
        <el-input
          v-model="pubData.title"
          placeholder="请输入文章标题"
          style="width: 400px"
        ></el-input>
      </el-form-item>
      <el-form-item label="频道：" style="max-width: 400px" prop="channel_id">
        <ChannelSelect v-model:model-value="pubData.channel_id"></ChannelSelect>
      </el-form-item>
      <el-form-item label="封面：" prop="cover">
        <el-radio-group v-model="pubData.cover.type" @change="changeCoverType">
          <el-radio :value="1">单图</el-radio>
          <el-radio :value="3">三图</el-radio>
          <el-radio :value="0">无图</el-radio>
          <el-radio :value="-1">自动</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item>
        <div v-if="pubData.cover.type === 1 || pubData.cover.type === 3">
          <el-upload
            ref="uploadRef"
            action=""
            list-type="picture-card"
            :http-request="uploadFile"
            :limit="pubData.cover.type"
            v-model:file-list="fileList"
            :on-remove="onRemove"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>

          <el-dialog v-model="dialogVisible">
            <img w-full :src="dialogImageUrl" alt="Preview Image" />
          </el-dialog>
        </div>
      </el-form-item>

      <el-form-item label="内容：" prop="content">
        <div style="width: 100%">
          <QuillEditor
            ref="cotentRef"
            v-model:content="pubData.content"
            @blur="onCheckContent"
            contentType="html"
            :options="editorOptions"
          ></QuillEditor>
        </div>
      </el-form-item>

      <el-form-item label="" v-if="route.params.id">
        <el-button type="primary" @click="onEdit(false)">编辑文章</el-button>
        <el-button @click="onEdit(true)">存入草稿</el-button>
      </el-form-item>
      <el-form-item label="" v-else>
        <el-button type="primary" @click="onSubmit(false)">发表文章</el-button>
        <el-button @click="onSubmit(true)">存入草稿</el-button>
      </el-form-item>
      <!-- {{ pubData }} -->
    </el-form>
  </el-card>
</template>

<style scoped>
:deep(.ql-editor) {
  width: 100%;
  min-height: 300px;
}
/* ::v-deep .el-upload-list__item{
  transition: none;
} */
</style>
